Øvelse 1_1

I Øvelsen skal vi opbygge et parkerings ssystem hvor flere biler kan forespørge om de må køre ind, er der plads i garagen kan bilen køre ind og døren til garagen lukker så igen. Ligeledes skal bilen kunne køre ud.
I første del af opgaven starter vi med at lave koden således at en bil kan køre ind og ud, den skal stadig forespørge om dette er muligt.
Vi løser problemet med multithreading. Vi oprette en lock, denne tages når man går ind i tråden. ved hjælp af conditionels kan man så gå fra den ene tråd over i den ande, altså man lægger den ene til at sove imens at den anden arbejder i locken.
#include <iostream>
#include <pthread.h>
#include <signal.h>
 
using namespace std;
 
bool carWaiting = false;
bool doorOpen = true;
bool openParkingSpace;
bool closeParkingSpace;
int amountOfCarsInGarage;
 
const int thread_number = 1;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t entry = PTHREAD_COND_INITIALIZER;
 
 
void *carDriverThread(void* arg)
{
  void driverToParking(void* );//ankommer til parkering
 
  cout << "ankommer til parkering" << endl;
  sleep(3);
  pthread_mutex_lock(&lock);
 
  carWaiting = true;
 
  cout << "bilen venter" << endl;
 sleep(2);
 
  pthread_cond_signal(&entry);
 
  while(!doorOpen);
 
  pthread_cond_wait(&entry, &lock);//hopper til næste tråd, condWait
    amountOfCarsInGarage++;
    cout << "bilen køre ind i p-kælderen" << endl;
    sleep(5);
  carWaiting = false;
  cout << "der er ingen biler i kø" << endl;
  pthread_cond_signal(&entry);
  pthread_mutex_unlock(&lock);//Unlock mutex, hopper til sidste condWait i parkingSpaceThread
 
  sleep(10);
 
  cout << "bilen køre ud igen" << endl;
 
}
 
void *parkingSpaceThread(void* arg )
{
  pthread_mutex_lock(&lock);
 
  while(carWaiting = false)
    cout << "der er ikke nogen biler i køen" << endl;
 
  pthread_cond_wait(&entry, &lock);//modtager tråd fra CarDriverThread
    cout << "hvis der er en bil der vænter" << endl;
 
      cout << "døren er åben og der er "<< amountOfCarsInGarage << " biler i garagen" << endl;
      doorOpen = true;
 
  pthread_cond_signal(&entry);
  while(carWaiting)
    pthread_cond_wait(&entry, &lock);//hopper tilbage til conWait i CarDriverThread
//  closeParkingSpace();//lukker parkering efter unlock i CarDriverThread
  doorOpen = false;
  cout << "døren er lukket og der er " << amountOfCarsInGarage << " biler i garagen" << endl;
  pthread_mutex_unlock(&lock);//frigiver mutex
}
 
 
int main()
{
  pthread_t car, park;
 
  pthread_create(&car, NULL, carDriverThread, NULL);
  pthread_create(&park, NULL, parkingSpaceThread, NULL);
 
  pthread_join(car, NULL);
  pthread_join(park, NULL);
 
  return 0;
}
 

Udprint:
ankommer til parkering
bilen venter
hvis der er en bil der vænter
døren er åben og der er 0 biler i garagen
bilen køre ind i p-kælderen
der er ingen biler i kø
døren er lukket og der er1 biler i garagen
bilen køre ud igen




Øvelse1_2

I denne del af øvelsen skal vi udvide del 1.1 til at fungerer med flere biler
dette gøres for at undgå eventuelle deadlocks hvilket kan fremkomme hvis en thread sætter vores kondision true hvorefter at dan anden thread sætter konditonen false.

til dette ændres kø fra at være en bolsk variable der enten kan være true eller false til at være en int der kan arbejde med flere biler.
nede i selve koden bliver vores true værdier sat til at inkrementere vores kø variabler ligeledes sættes vores false til at dekrementerer vores kø tæller.

nede i vores while løkker sættes vores kondition til at arbejde med værdien når køen er på nul biler for den første while og den anden while sættes til at loope når køen er støre end nul.

void* carController(void* threadid)
{
    int *id = reinterpret_cast<int*>(threadid);
 
    printf("   %d: ankommer til pkælderen\n", id);
    pthread_mutex_lock(&mutexEntry);
 
    carEntryWait++;
    pthread_cond_signal(&entry);
 
    while(!entryPortOpened)
        pthread_cond_wait(&entry, &mutexEntry);
 
    printf("   %d: kører ind i garagen\n", id);
 
    carEntryWait--;
    pthread_cond_signal(&entry);
    pthread_mutex_unlock(&mutexEntry);
 
    sleep(3); //Vente tid.. Denne kan ændres efter ønske.
 
    pthread_mutex_lock(&mutexExit);
    carExitWait++;
    pthread_cond_signal(&exit);
 
    while(!exitPortOpened)
    {
        pthread_cond_wait(&exit, &mutexExit);
    }
    printf("   %d: kører ud\n", id);
 
    carExitWait--;
    pthread_cond_signal(&exit);
    pthread_mutex_unlock(&mutexExit);
}
 
 
void* entryController(void* threadid)
{
    while(1)
    {
        pthread_mutex_lock(&mutexEntry);
        while(carEntryWait == 0)
              pthread_cond_wait(&entry, &mutexEntry);
 
        printf("åbner indgangen \n");
 
        entryPortOpened = true;
        pthread_cond_signal(&entry);
 
        while(entryPortOpened)
            pthread_cond_wait(&entry, &mutexEntry);
 
        printf("Lukker indgangen \n");
        entryPortOpened = false;
        pthread_mutex_unlock(&mutexEntry);
    }
}
 
 
void* exitController(void* threadid)
{
    while(1)
    {
        pthread_mutex_lock(&mutexExit);
        while(carExitWait == 0)
            pthread_cond_wait(&exit, &mutexExit);
 
        cout << "åbner udgangen" << endl;
 
        exitPortOpened = true;
        pthread_cond_signal(&exit);
 
        while(carExitWait > 0)
            pthread_cond_wait(&exit, &mutexExit);
 
        cout << "lukker udgangen" << endl;
 
        pthread_mutex_unlock(&mutexExit);
    }
}
 
 

udskrift på skærm
   1: ankommer til pkælderen
   0: ankommer til pkælderen
åbner indgangen
   2: ankommer til pkælderen
   2: kører ind i garagen
   3: ankommer til pkælderen
   1: kører ind i garagen
   3: kører ind i garagen
   0: kører ind i garagen
åbner udgangen
   3: kører ud
   1: kører ud
   0: kører ud
   2: kører ud
lukker udgangen





Konklusion
vi har i øvelsen læt at man gennem signaler kan få forskellige threads til at aktivere hinnandens ellementer, dette giver os
fordele til at udvikele mere komplekse strukture i vores kode.


http://multithreading.resourcezen.com/problem-with-cond-signal-or-lock-release
https://computing.llnl.gov/tutorials/pthreads/
http://randu.org/tutorials/threads/